package com.fzk.blog.settings.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fzk.blog.bean.Type;
import com.fzk.blog.bean.vo.TypeInfo;
import com.fzk.blog.blog.service.IRedisService;
import com.fzk.blog.exception.MyException;
import com.fzk.blog.mapper.TypeMapper;
import com.fzk.blog.settings.service.ITypeService;
import com.fzk.blog.utils.MyJsonUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
 * @author fzk
 * @date 2021-08-16 17:24
 */
@Service
public class TypeService implements ITypeService {
    @Resource
    private TypeMapper typeMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @Transactional//开启事务
    public TypeInfo insertType(Type type, int loginId) throws JsonProcessingException {
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();

        // 1.先检查有没有相同的分类名称
        List<Type> types = typeMapper.getTypeByName(type.getName());
        if (types.size() != 0)
            throw new MyException(400, "分类名：" + type.getName() + " 已经存在");

        // 2.完善插入信息
        type.setCreateBy(loginId);
        type.setEditBy(loginId);
        type.setFlag(0);

        // 3.插入
        int i = typeMapper.insert(type);
        if (i != 1)
            throw new MyException(500, "插入失败");

        // 4. 获取typeinfo
        TypeInfo typeInfo= typeMapper.getTypeInfoById(type.getId());

        // 5. 放入redis
        opsForValue.set("typeInfo:id:"+typeInfo.getId(),MyJsonUtil.writeToString(typeInfo), Duration.ofMillis(1000*60*60));

        // 6. 清空redis的typeInfoList
        stringRedisTemplate.delete("typeInfoList");

        return typeInfo;
    }

    @Override
    public List<TypeInfo> getTypeInfoList() throws JsonProcessingException {
        List<TypeInfo> typeInfoList = null;
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        // 1 先去redis拿
        String json = opsForValue.get("typeInfoList");
        // 2 没有的话，从数据库拿，并放入redis
        if (json == null) {
            typeInfoList = typeMapper.getTypeInfoList();
            opsForValue.set("typeInfoList", MyJsonUtil.writeToString(typeInfoList),Duration.ofMillis(1000*60*60));
        } else
            typeInfoList = MyJsonUtil.toBeanArray(json, TypeInfo.class);
        return typeInfoList;
    }

    @Override
    public TypeInfo getTypeById(Integer typeId) throws JsonProcessingException {
        TypeInfo typeInfo = null;
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        // 1. 从redis拿
        String json = opsForValue.get("typeInfo:id:" + typeId);

        // 2 没有的话，从数据库拿，并放入redis
        if (json == null) {
            typeInfo = typeMapper.getTypeInfoById(typeId);
            if (typeInfo == null)
                throw new MyException(400, "id无效：" + typeId);
            opsForValue.set("typeInfo:id:"+typeId,MyJsonUtil.writeToString(typeInfo),Duration.ofMillis(1000*60*60));
        }else
            typeInfo=MyJsonUtil.toBean(json,TypeInfo.class);

        return typeInfo;
    }

    @Override
    @Transactional//开启事务
    public TypeInfo updateType(Type type, int loginId) throws JsonProcessingException {
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();

        // 0.检查是否已经存在该名称的分类
        List<Type> types = typeMapper.getTypeByName(type.getName());
        if (types.size() != 0)
            throw new MyException(400, "该分类名已经存在：" + type.getName());
        // 1.完善修改信息
        type.setEditBy(loginId);

        // 2.更新操作
        int i = typeMapper.updateById(type);
        if (i != 1)
            throw new MyException(400, "更新失败，id：" + type.getId());

        // 3.查询typeInfo
        TypeInfo typeInfo= typeMapper.getTypeInfoById(type.getId());

        // 4. 放入redis
        opsForValue.set("typeInfo:id:"+type.getId(),MyJsonUtil.writeToString(typeInfo),Duration.ofMillis(1000*60*60));

        // 5. 删除redis里的typeInfoList
        stringRedisTemplate.delete("typeInfoList");
        return typeInfo;
    }

    @Override
    @Transactional//开启事务
    public TypeInfo deleteType(int typeId, int loginId) {
        TypeInfo typeInfo = typeMapper.getTypeInfoById(typeId);
        if (typeInfo == null)
            throw new MyException(400, "id无效：" + typeId);
        int i = typeMapper.logicalDeleteById(typeId, loginId);
        if (i != 1)
            throw new MyException(500, "删除失败，id：" + typeId);

        // 删redis缓存
        stringRedisTemplate.delete("typeInfoList");
        stringRedisTemplate.delete("typeInfo:id"+typeId);

        return typeInfo;
    }
}
